﻿using GrainManage.Entities.Image;
using System;
using System.Collections.Generic;
using System.IO;

namespace GrainManage.Server.Business
{
    public class ImageBusiness : BaseBusiness, GrainManage.Interface.IImage
    {
        //************************************************POST************************************************
        public byte[] DownLoad(InputDownLoad input)
        {
            var absolutePath = GetAbsolutePath(input.ImageID, input.Authentication.UserName);
            var data = ReadFile(absolutePath);
            return data;
        }

        public OutputGetImages GetImages(InputGetImages input)
        {
            var result = new OutputGetImages();
            try
            {
                var service = ObjectFactory.ImageService;
                result.Images = service.GetImages(input, result, input.Authentication.UserName);
                if (input.DesiredSize != null && input.DesiredSize.Width > 0 && input.DesiredSize.Height > 0)
                {
                    foreach (var image in result.Images)
                    {
                        image.File = GetThumb(input.DesiredSize.Width, input.DesiredSize.Height, image.File);
                    }
                }

                if (result.Images.Count == 0)
                {
                    SetResponse(StatusCode.NoData, input, result);
                }
                else
                {
                    SetResponse(StatusCode.Success, input, result);
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, input, result, e);
            }

            return result;
        }

        public OutputGetImageFile GetImageFile(InputGetImageFile input)
        {
            var result = new OutputGetImageFile();
            try
            {
                var userName = input.Authentication != null ? input.Authentication.UserName : null;
                var absolutePath = GetAbsolutePath(input.ImageID, input.Authentication.UserName);
                var data = ReadFile(absolutePath);
                if (input.DesiredSize != null && input.DesiredSize.Width > 0 && input.DesiredSize.Height > 0)
                {
                    data = GetThumb(input.DesiredSize.Width, input.DesiredSize.Height, data);
                }
                if (data != null)
                {
                    SetResponse(StatusCode.Success, input, result);
                }
                else
                {
                    SetResponse(StatusCode.FileNotExist, input, result);
                }
            }
            catch (IOException e)
            {
                SetResponse(StatusCode.IOError, input, result, e);
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, input, result, e);
            }

            return result;
        }

        public OutputGetImageUrl GetImageUrl(InputGetImageUrl input)
        {
            var result = new OutputGetImageUrl { ImageUrls = new Dictionary<int, string>() };
            try
            {
                var userName = input.Authentication.UserName;
                foreach (var imageID in input.ImageIDs)
                {
                    var absolutePath = GetAbsolutePath(imageID, userName);
                    if (IsFileExists(absolutePath))
                    {
                        result.ImageUrls[imageID] = GetImageUrl(imageID, userName);
                    }
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, input, result, e);
            }
            return result;
        }

        public OutputInsert Insert(InputInsert input)
        {
            var result = new OutputInsert();
            try
            {
                input.Image.Creator = input.Authentication.UserName;
                var service = ObjectFactory.ImageService;
                int imageID = service.GetImageID(input.Image.ImageName, input.Authentication.UserName);
                if (imageID > 0)
                {
                    SetResponse(StatusCode.FileHasExist, input, result);
                }
                else
                {
                    result.ImageID = service.Insert(input.Image);
                    if (result.ImageID > 0)
                    {
                        var absolutePath = GetAbsolutePath(result.ImageID, input.Authentication.UserName);
                        SaveFile(absolutePath, input.Image.File);
                        SetResponse(StatusCode.Success, input, result);
                    }
                    else
                    {
                        SetResponse(StatusCode.InsertFailed, input, result);
                    }
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, input, result, e);
            }

            return result;
        }

        public OutputUpdate Update(InputUpdate input)
        {
            var result = new OutputUpdate();
            try
            {
                input.Image.Creator = input.Authentication.UserName;
                var service = ObjectFactory.ImageService;
                if (service.Update(input.Image) > 0)
                {
                    if (input.Image.File != null)
                    {
                        var absolutePath = GetAbsolutePath(input.Image.ImageID, input.Authentication.UserName);
                        DeleteFile(absolutePath);
                        SaveFile(absolutePath, input.Image.File);
                    }
                    SetResponse(StatusCode.Success, input, result);
                }
                else
                {
                    SetResponse(StatusCode.UpdateFailed, input, result);
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, input, result, e);
            }
            return result;
        }

        public OutputDelete Delete(InputDelete input)
        {
            var result = new OutputDelete();
            try
            {
                var path = GetAbsolutePath(input.ImageID, input.Authentication.UserName);
                if (IsFileExists(path))
                {
                    var service = ObjectFactory.ImageService;
                    if (service.Delete(input.ImageID, input.Authentication.UserName) > 0)
                    {
                        System.IO.File.Delete(path);
                        SetResponse(StatusCode.Success, input, result);
                    }
                    else
                    {
                        SetResponse(StatusCode.DeleteFailed, input, result);
                    }
                }
                else
                {
                    SetResponse(StatusCode.FileNotExist, input, result);
                }
            }
            catch (Exception e)
            {
                SetResponse(StatusCode.Failed, input, result, e);
            }

            return result;
        }

        public static string GetImageUrl(int imageID, string userName)
        {
            var image = ObjectFactory.ImageService.Get(imageID, userName);
            if (string.IsNullOrEmpty(userName))
            {
                return string.Format("{0}/{1}", AppConfig.GetValue("ImageServerPath"), image.ImageName);
            }
            else
            {
                return string.Format("{0}/{1}/{2}", AppConfig.GetValue("ImageServerPath"), userName, image.ImageName);
            }
        }

        //生成缩略图
        private byte[] GetThumb(int width, int height, byte[] data)
        {
            var thumbData = data;
            if (data != null)
            {
                thumbData = new Util.Thumbnail().GetThumbnail(width, height, data, Util.Thumbnail.ResizeType.Zoom);
            }
            return thumbData;
        }

        private string GetAbsolutePath(int imageID, string userName)
        {
            var rootPath = AppConfig.GetValue("ImagePath");
            var service = ObjectFactory.ImageService;
            var image = service.Get(imageID, userName);
            var absolutePath = string.IsNullOrEmpty(image.Creator) ? Path.Combine(rootPath, image.ImageName) : Path.Combine(rootPath, userName, image.ImageName);
            return absolutePath;
        }

        private bool SaveFile(string absolutePath, byte[] photo)
        {
            bool isSuccess = false;
            if (photo != null && !IsFileExists(absolutePath))
            {
                var directoryPath = Path.GetDirectoryName(absolutePath);
                if (!Directory.Exists(directoryPath))
                {
                    Directory.CreateDirectory(directoryPath);
                }
                System.IO.File.WriteAllBytes(absolutePath, photo);
                isSuccess = true;
            }
            return isSuccess;
        }

        private byte[] ReadFile(string absolutePath)
        {
            byte[] file = null;
            if (IsFileExists(absolutePath))
            {
                file = System.IO.File.ReadAllBytes(absolutePath);
            }
            return file;
        }

        private bool DeleteFile(string absolutePath)
        {
            bool isSuccess = false;
            if (IsFileExists(absolutePath))
            {
                System.IO.File.Delete(absolutePath);
                isSuccess = true;
            }
            return isSuccess;
        }

        private bool IsFileExists(string absolutePath)
        {
            return System.IO.File.Exists(absolutePath);
        }

    }
}
